package org.sharkness.jsf.support;

import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

import org.sharkness.business.entity.Model;
import org.sharkness.business.factory.ModelFactory;
import org.sharkness.business.support.ModelService;
import org.sharkness.web.component.ControllerComponent;

public abstract class ModelController<T extends Model, Service extends ModelService<T>> implements ControllerComponent {

	private static final long serialVersionUID = 1L;
	
	private T model;
	
	private Class<T> klassModel;
	
    private DataModel<T> dataModel;
    
    public ModelController() {
    	try {
        	this.klassModel = ModelFactory.getClass(this);
        	model = newInstanceModel();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
    public List<T> getListModel() throws Exception {
    	return getModelService().list();
    }
    
	public DataModel<T> getListDataModel() throws Exception {
        dataModel = new ListDataModel<T>(getListModel());
        return dataModel;
    }

    public T getModel() {
        return model;
    }

    public void setModel(T model) {
        this.model = model;
    }

    public void prepareAddModel(ActionEvent actionEvent){
        model = newInstanceModel();
    }

    public void prepareEditModel(ActionEvent actionEvent){
        model = (T)(dataModel.getRowData());
    }

    public String deleteModel() throws Exception{
    	getModelService().delete(dataModel.getRowData());
        return "index";
    }

    public void addModel(ActionEvent actionEvent) throws Exception{
    	if (getModelService().insert(modelProcessBeforeSave(model))) {
    		message("Sucesso na inser&ccedil;&atilde;o");
    	} else {
    		message("Problema na inser&ccedil;&atilde;o");
    	}
    }

    public void editModel(ActionEvent actionEvent) throws Exception{
    	if (getModelService().update(modelProcessBeforeSave(model))) {
    		message("Sucesso na alter&ccedil;&atilde;o");
    	} else {
    		message("Problema na alter&ccedil;&atilde;o");
    	}
    }

    public void saveModel(ActionEvent actionEvent) throws Exception{
    	if (model.getId() != null && model.getId() > 0) {
    		editModel(actionEvent);
    	} else {
    		addModel(actionEvent);
    	}
    }
    
    protected T modelProcessBeforeSave(T model) {
		return model;
	}
    
    public abstract Service getModelService();
    
    private T newInstanceModel() {
    	try {
    		return klassModel.newInstance();			
		} catch (Exception e) {
			return null;
		}
    }
    
    private void message(String summary) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary,  null);
		FacesContext.getCurrentInstance().addMessage(null, message);
	}
    
}
